/*
 * Copyright (c) 2024 Shenzhen Kaihong Digital Industry Development Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef SLE_SSAP_SERVER_H
#define SLE_SSAP_SERVER_H

#include <iostream>
#include <memory>
#include "sle_ssap_server_config.h"
#include "sle_common_config.h"
#include "sle_error_code.h"

namespace OHOS {
namespace NearLink {
namespace SleStandard {
class SleSsapServerCallback {
public:
    /**
     *   @brief A destructor used to delete the <b>SleSsapServerCallback</b> instance.
     */
    virtual ~SleSsapServerCallback() = default;

    /**
     *   @brief   Read Request callback
     *
     *   @param   [in] connectId - connnection id
     *   @param   [in] readCbPara - read callback param
     *   @param   [in] errCode - delete all services result error code
     *   @return  None
     */
    virtual void OnReadRequest(uint16_t connectId, const SsapsReqReadCbParam &readCbPara, SleErrorCode errCode) = 0;

    /**
     *   @brief   Write request callback
     *
     *   @param   [in] connectId - connnection id
     *   @param   [in] writeCbPara - write callback param
     *   @param   [in] errCode - delete all services result error code
     *   @return  None
     */
    virtual void OnWriteRequest(uint16_t connectId, const SsapsReqWriteCbPara &writeCbPara, SleErrorCode errCode) = 0;

    /**
     *   @brief   Exchange mtu info callback
     *
     *   @param   [in] connectId - connnection id
     *   @param   [in] info - mtu info
     *   @param   [in] errCode - delete all services result error code
     *   @return  None
     */
    virtual void OnMtuInfoChanged(uint16_t connectId, const SsapMtuInfo &info, SleErrorCode errCode) = 0;
};

class SleSsapServer {
public:
    /**
     *   @brief   A constructor used to create a <b>SleSsapServer</b> instance.
     *
     *   @param   [in] uuid - server application uuid
     */
    explicit SleSsapServer(const SleUuid &uuid);

    /**
     *   @brief   A constructor used to create a <b>SleSsapServer</b> instance.
     */
    SleSsapServer() = delete;

    /**
     *   @brief A constructor used to delete a <b>SleSsapServer</b> instance.
     */
    ~SleSsapServer();

    /**
     *   @brief   Add ssap service service sync
     *
     *   @param   [in] uuid - service uuid
     *   @param   [in] isPrimary - is primary service or not
     *   @param   [out] handle - service handle
     *   @return  SleErrorCode
     */
    SleErrorCode AddService(const SleUuid &uuid, bool isPrimary, uint16_t &handle);

    /**
     *   @brief   Add ssap property sync
     *
     *   @param   [in] serviceHandle - service handle
     *   @param   [in] param - property param
     *   @param   [out] handle - property handle
     *   @return  SleErrorCode
     */
    SleErrorCode AddProperty(uint16_t serviceHandle, const SsapsPropertyParam &param, uint16_t &handle);

    /**
     *   @brief   Add ssap descriptor sync
     *
     *   @param   [in] serviceHandle - service handle
     *   @param   [in] propHandle - property handle
     *   @param   [in] param - descriptor param
     *   @return  SleErrorCode
     */
    SleErrorCode AddDescriptor(uint16_t serviceHandle, uint16_t propHandle, const SsapsDescriptorParam &param);

    /**
     *   @brief   Remove all services sync
     *
     *   @return  SleErrorCode
     */
    SleErrorCode RemoveAllServices();

    /**
     *   @brief   Start a ssap service sync
     *
     *   @param   [in] serviceHandle - service handle
     *   @return  SleErrorCode
     */
    SleErrorCode StartService(uint16_t serviceHandle);

    /**
     *   @brief   Send response when receive the request need to response by user aysnc
     *
     *   @param   [in] connectId - connection id
     *   @param   [in] param - response paramter
     *   @return  SleErrorCode
     */
    SleErrorCode SendResponse(uint16_t connectId, const SsapsSendRspParam &param);

    /**
     *   @brief   Send indication or notification to remote device sync
     *
     *   @param   [in] connectId - connection id
     *   @param   [in] param - notify/indicate parameter
     *   @return  SleErrorCode
     */
    SleErrorCode NotifyIndicate(uint16_t connectId, const SsapsNotifyParam &param);

    /**
     *   @brief   Send indication or notification to remote device by uuid sync
     *
     *   @param   [in] connectId - connection id
     *   @param   [in] param - notify/indicate parameter
     *   @return  SleErrorCode
     */
    SleErrorCode NotifyIndicateByUuid(uint16_t connectId, const SsapsNotyfyByUuidParam &param);

    /**
     *   @brief   Set server info before connected async
     *
     *   @param   [in] info - mtu info of the connection
     *   @return  SleErrorCode
     *
     *   @note Receive callback info in OnMtuInfoChanged.
     */
    SleErrorCode SetServerMtuInfo(const SsapMtuInfo &info);

    /**
     *   @brief   Register ssap server callback sync
     *
     *   @param   [in] callback - callback
     *   @return  SleErrorCode
     */
    SleErrorCode RegisterServerCallback(std::shared_ptr<SleSsapServerCallback> callback);

    /**
     *   @brief   Unregister ssap server callback sync
     *
     *   @param   [in] callback - callback
     *   @return  SleErrorCode
     */
    SleErrorCode UnregisterServerCallback(std::shared_ptr<SleSsapServerCallback> callback);

private:
    class SleSsapServerImpl;
    std::unique_ptr<SleSsapServerImpl> pimpl_;
    SLE_DISALLOW_COPY_AND_ASSIGN(SleSsapServer);
};
} // SleStandard
} // NearLink
} // OHOS

#endif // SLE_SSAP_SERVER_H